package common;


import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.Vector;

import common.exception.*;

/** ServerInterface
 * @author Flavio Ferrara
 * Definisce i metodi invocabili dal client e il formato dell'eventuale risposta
 * 
 * Nel caso di insuccesso i metodi lanciano un'eccezione, a seconda del tipo di errore (ComException, GameException, LoginException, ecc.)
 */

public interface ServerInterface extends Remote{


	/**
	 * Il giocatore con il token passato richiede di accedere alla partita
	 * Se attualmente ci sono già MAX_GIOCATORI in partita, viene sollevata una FullMatchException
	 */
	public abstract void inGame(int token) throws InvalidTokenException, FullMatchException, RemoteException;


	/**
	 * Il giocatore con il token passato richiede di creare la sua specie
	 * @param type : {'c','e'}
	 * @throws BusyNameException se il nome è già assegnato
	 */
	public abstract void newSpecies(int token, String name, char type) throws InvalidTokenException, BusyNameException, RemoteException;



	/**
	 * Un giocatore richiede la registrazione
	 * @param username
	 * @param psw
	 * @throws BusyNameException se il nome è già assegnato
	 */
	public abstract void newUser(String username, String psw) throws BusyNameException, RemoteException;



	/**
	 * Il giocatore con il token passato richiede di far crescere il dino specificato
	 * 
	 * @throws InvalidTokenException se il token non esiste
	 * @throws GameException se c'è stata un'infrazione di gioco
	 */
	public abstract void growDino(int token, int idDino) throws InvalidTokenException, NotInMatchException, InvalidIdException, GameException, RemoteException;

	
	/**
	 * Il giocatore con il token passato richiede di far figliare il dino specificato
	 * 
	 * @return l'ID del nuovo dinosauro
	 * @throws InvalidTokenException se il token non esiste
	 * @throws GameException se c'è stata un'infrazione di gioco
	 */
	public abstract int egg(int token, int idDIno)  throws InvalidTokenException, NotInMatchException, InvalidIdException, GameException, RemoteException;

	
	/**
	 * Il giocatore con il token passato richiede la classifica
	 * @return un oggetto Ranking con la classifica completa
	 * @throws InvalidTokenException se il token non esiste
	 */
	public abstract Ranking getRanking(int token) throws InvalidTokenException, RemoteException;



	/**
	 * Il giocatore con il token passato richiede la lista dei giocatori IN PARTITA
	 * 
	 * @return un array di stringhe con la lista di username
	 * @throws InvalidTokenException se il token non esiste
	 */
	public abstract String[] getPlayers(int token) throws InvalidTokenException, RemoteException;



	/**
	 * il giocatore con il token passato richiede la lista dei propri dinosauri
	 * 
	 * @return un array di interi con gli ID dei dinosauri
	 * @throws InvalidTokenException se il token non esiste
	 * @throws NotInMatchException se il giocatore non è in partita
	 */
	public abstract Integer[] getDinoList(int token) throws InvalidTokenException, NotInMatchException, RemoteException;


	
	/**
	 * il giocatore richiede la mappa generale, con le PROPRIE limitazioni di visuale
	 * 
	 * @return un oggetto UserMap che contiene la mappa intera 
	 * @throws InvalidTokenException se il token non esiste
	 * @throws NotInMatchException se il giocatore non è in partita
	 */
	public abstract UserMap getMap(int token) throws InvalidTokenException, NotInMatchException, RemoteException ;



	/**
	 * Il giocatore richiede lo stato di uno dei propri dinosauri
	 * 
	 * @return un vector così composto: 
	 * {Username:string, SpecieName:string, SpecieType:char({'c','e'}), CasellaX:int, CasellaY:int, Dimensione:int, 
	 * Energia:int, Turni vissuti:int}
	 * Gli ultimi 2 valori sono presenti SOLO se il dinosauro appartiene al giocatore
	 * @throws InvalidTokenException se il token non esiste
	 * @throws NotInMatchException se il giocatore non è in partita
	 * @throws InvalidIdException se l'id non esiste
	 */
	public abstract Vector getDinoStat(int token, int idDino) throws InvalidTokenException, InvalidIdException, NotInMatchException, RemoteException;



	/**
	 * Il giocatore richiede la visuale di uno dei propri dinosauri
	 * 
	 * @return un oggetto UserMap che contiene la mappa "ristretta" di un dinosauro
	 * @throws InvalidTokenException se il token non esiste
	 * @throws NotInMatchException se il giocatore non è in partita
	 * @throws InvalidIdException se l'id non esiste o non gli appartiene
	 */
	public abstract UserMap getDinoVisual(int token, int idDino)  throws InvalidTokenException, InvalidIdException, NotInMatchException, RemoteException;

	
	/**
	 * Il giocatore richiede di spostare un dinosauro
	 * 
	 * @return il carattere {'v','n','x'} se rispettivamente c'è stato un combattimento vinto, perso, nessun combattimento
	 * @throws InvalidTokenException se il token non esiste
	 * @throws NotInMatchException se il giocatore non è in partita
	 * @throws InvalidIdException se l'id non esiste o non gli appartiene
	 * @throws GameException se c'è stata un'infrazione di gioco
	 */
	public abstract char move(int token, int idDino, int[] destination)  throws InvalidTokenException, InvalidIdException, NotInMatchException, GameException, RemoteException;


	
	/**
	 * Il giocatore richiede il login
	 * 
	 * @return l'intero che rappresenta il TOKEN
	 * @throws FailedAuthenticationException se il login è fallito
	 */
	public abstract int login(String username, String psw) throws FailedAuthenticationException, RemoteException;



	/**
	 * Il giocatore richiede il logout
	 * 
	 * @throws InvalidTokenException
	 */
	public abstract void logout(int token)  throws InvalidTokenException, RemoteException;


	/**
	 * Il giocatore richiede di passare il turno prima dello scadere
	 * 
	 * @throws InvalidTokenException
	 * @throws NotInMatchException se il giocatore non è in partita
	 * @throws GameException se non è il suo turno
	 */
	public abstract void skipTurn(int token) throws InvalidTokenException, NotInMatchException, GameException, RemoteException;



	/**
	 * Il giocatore richiede di utilizzare il proprio turno, prima del timeout
	 * 
	 * @throws InvalidTokenException
	 * @throws NotInMatchException se il giocatore non è in partita
	 * @throws GameException se non è il suo turno
	 */
	public abstract void useTurn(int token)  throws InvalidTokenException, NotInMatchException, GameException, RemoteException;



	/**
	 * Il giocatore richiede di uscire dalla Partita
	 * 
	 * @throws InvalidTokenException
	 */
	public abstract void outGame(int token) throws InvalidTokenException, RemoteException;
}
